<template>
  <div class="camera-container">
    <div class="camera-section">
      <div class="preview-wrapper">
        <div class="preview-label">实时预览</div>
        <video ref="video" class="camera-preview" v-show="isCameraActive"></video>
        <img v-if="photoData" :src="photoData" class="photo-preview">
        <div v-else-if="!isCameraActive" class="placeholder">
          <el-icon :size="50"><Camera /></el-icon>
          <p>请点击"打开摄像头"开始</p>
        </div>
      </div>
      
      <div class="button-group">
        <el-tooltip content="打开摄像头" placement="top">
          <el-button type="primary" @click="openCamera" :disabled="isCameraActive" circle>
            <el-icon><VideoCamera /></el-icon>
          </el-button>
        </el-tooltip>
        
        <el-tooltip content="关闭摄像头" placement="top">
          <el-button type="danger" @click="stopCamera" :disabled="!isCameraActive" circle>
            <el-icon><SwitchButton /></el-icon>
          </el-button>
        </el-tooltip>
        
        <el-tooltip content="拍照" placement="top">
          <el-button type="success" @click="takePhoto" :disabled="!isCameraActive" circle>
            <el-icon><Camera /></el-icon>
          </el-button>
        </el-tooltip>
        
        <el-tooltip content="重新拍照" placement="top">
          <el-button type="warning" @click="retakePhoto" :disabled="!photoData" circle>
            <el-icon><Refresh /></el-icon>
          </el-button>
        </el-tooltip>
      </div>
      
      <div class="status-indicator" :class="{ active: isCameraActive }">
        <span class="indicator-dot"></span>
        {{ isCameraActive ? '摄像头已开启' : '摄像头已关闭' }}
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { 
  VideoCamera,
  SwitchButton,
  Camera,
  Refresh
} from '@element-plus/icons-vue';

// 只暴露照片获取方法
defineExpose({
  getPhotoData,
  getPhotoBlob
});

const video = ref(null);
const stream = ref(null);
const isCameraActive = ref(false);
const photoData = ref(null);

// 获取照片的Base64数据
function getPhotoData() {
  return photoData.value;
}

// 获取照片的Blob对象
function getPhotoBlob() {
  if (!photoData.value) return null;
  return dataURLtoBlob(photoData.value);
}

// 将Base64转换为Blob
function dataURLtoBlob(dataurl) {
  const arr = dataurl.split(',');
  const mime = arr[0].match(/:(.*?);/)[1];
  const bstr = atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], { type: mime });
}

const openCamera = async () => {
  try {
    // 请求摄像头访问权限
    stream.value = await navigator.mediaDevices.getUserMedia({ 
      video: { 
        facingMode: 'user', // 优先使用前置摄像头
        width: { ideal: 1280 },
        height: { ideal: 720 }
      } 
    });
    
    video.value.srcObject = stream.value;
    video.value.play();
    isCameraActive.value = true;
    photoData.value = null;
  } catch (error) {
    console.error('无法访问摄像头:', error);
  }
};

const takePhoto = () => {
  if (!isCameraActive.value) return;
  
  // 创建Canvas来捕获图像
  const canvas = document.createElement('canvas');
  canvas.width = video.value.videoWidth;
  canvas.height = video.value.videoHeight;
  
  // 绘制视频帧到Canvas
  const ctx = canvas.getContext('2d');
  ctx.drawImage(video.value, 0, 0, canvas.width, canvas.height);
  
  // 将Canvas转换为Base64图像数据
  photoData.value = canvas.toDataURL('image/jpeg', 0.9);
  
  // 拍照后自动关闭摄像头
  stopCamera();
};

// 停止摄像头
const stopCamera = () => {
  if (stream.value) {
    stream.value.getTracks().forEach(track => track.stop());
    stream.value = null;
    if (video.value) {
      video.value.srcObject = null;
    }
  }
  isCameraActive.value = false;
};

const retakePhoto = () => {
  photoData.value = null;
  openCamera();
};
</script>

<style scoped>
.camera-container {
  max-width: 700px;
  margin: 0 auto;
  padding: 20px;
  border-radius: 12px;
  background: #ffffff;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
}

.camera-section {
  text-align: center;
}

.camera-preview, .photo-preview {
  width: 100%;
  max-width: 640px;
  max-height: 480px;
  margin-bottom: 20px;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  border: 1px solid #ebeef5;
  background-color: #000;
  aspect-ratio: 4/3;
  object-fit: cover;
}

.button-group {
  display: flex;
  justify-content: center;
  gap: 15px;
  flex-wrap: wrap;
  margin: 20px 0;
}

.status-indicator {
  text-align: center;
  color: #909399;
  font-size: 14px;
  margin-top: 15px;
}

.status-indicator.active {
  color: #67c23a;
}

.indicator-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #909399;
  margin-right: 8px;
}

.status-indicator.active .indicator-dot {
  background: #67c23a;
}

.preview-wrapper {
  position: relative;
  margin-bottom: 20px;
  border-radius: 8px;
  background: #f8fafc;
  padding: 15px;
  box-shadow: inset 0 0 10px rgba(0,0,0,0.05);
}

.preview-label {
  position: absolute;
  top: -10px;
  left: 20px;
  background: #409eff;
  color: white;
  padding: 3px 15px;
  border-radius: 15px;
  font-size: 14px;
  box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}

.placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 300px;
  color: #909399;
  background: #f0f2f5;
  border-radius: 5px;
}

.placeholder p {
  margin-top: 15px;
  font-size: 16px;
}
</style>